home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / BAC.ASM < prev    next >
Assembly Source File  |  1986-02-05  |  14KB  |  364 lines

  1. BAC    segment para public 'code'
  2.     assume    cs:BAC, ds:BAC, es:BAC, ss:NOTHING
  3.     org    100h        ; .COM format
  4. BEGIN:
  5.     jmp    CODE_START    ; Jump around data declarations
  6. DECLARE:            ; Messages, Storage Areas, Equates
  7.     COPYRIGHT    db    'BACopy (C) 1985, Dickinson Associates Inc.'
  8.             db    13,10,'$'
  9.     PATH_FILE_LEN    equ    77  ;Length = 1, Path = 63, FileName = 12, 0 = 1
  10.     SOURCE_FILE    db    PATH_FILE_LEN dup (0)
  11.     TARGET_PATH    db    PATH_FILE_LEN dup (0)
  12.     SOURCE_END    dw    0
  13.     TARGET_END    dw    0
  14.     SOURCE_HANDLE    dw    0
  15.     TARGET_HANDLE    dw    0
  16.     SOURCE_DTA    db    44 dup(0)
  17.     TARGET_DTA    db    44 dup(0)
  18.     VALID_IN    db    'abcdefghijklmnopqrstuvwxyz,;=',9
  19.     VALID_OUT    db    'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
  20.     VALID_NUM    equ    $ - VALID_OUT + 1
  21.     BLKSIZE     dw    0
  22.     LAST_BLOCK    db    0
  23.     EVENT_FLAG    db    0
  24.     ERR_HEAD    db    10,13,'BACopy Error - $'
  25.     NO_PARMS    db    'Correct Syntax is:',13,10,10
  26.     db   'BACopy [d:][source_path]source_filename[.ext] [d:][target_path]$'
  27.     FILE_NOT_FOUND    db    'File Not Found$'
  28.     SOURCE_ERROR    db    'Opening Source File$'
  29.     CREATE_ERROR    db    'Creating Target File$'
  30.     TARGET_FULL    db    '!!',10,10,13,'Target Disk is Full',13,10,10
  31.     db    'Insert New Disk and Press [Enter]',7,'$'
  32.     ERR_TAIL    db    10,10,13,' . . . Aborting',10,13,13,'$'
  33.     CONFIRM_MSG_1    db    ' . . $'
  34.     CONFIRM_MSG_2    db    'BACopied to . . $'
  35.     END_LINE    db    10,13,'$'
  36.     NOTHING_TO_DO    db    13,10,'No Files Needed to be BACopied',13,10,'$'
  37. ;
  38. CODE_START:    ; Parse command line into source & target parameters
  39.     mov    dx,offset COPYRIGHT    ; Display copyright notice
  40.     mov    ah,9h
  41.     int    21h
  42.     mov    si,80h            ; PSP parameter byte count pointer
  43.     mov    cl,[si]         ; Move byte count to CL
  44.     xor    ch,ch            ; Zero CH
  45.     jcxz    NO_PARMS_PASSED     ; If CX is zero, there are no parameters
  46.     mov    dx,cx            ; Save byte count in dx
  47.     inc    si            ; Point to parameter area
  48.     mov    di,si            ; Copy SI to DI for cleanup routine
  49.     cld                ; Set direction flag to forward
  50. CLEAN_PARMS:    ; Change valid delimiters to blanks, lower to upper case
  51.     lodsb                ; Load each character to AL
  52.     push    di            ; Save DI on stack
  53.     mov    di,offset VALID_IN    ; Point to table of valid inputs
  54.     push    cx            ; Save CX on stack
  55.     mov    cx,VALID_NUM        ; Set CX to number of inputs to look for
  56. repne    scasb                ; See if any are in AL
  57.     jcxz    CLEAN_END        ; If not, change nothing
  58.     mov    bx,VALID_NUM        ; Set up BX to point to valid output
  59.     sub    bx,cx            ; This will leave BX one off
  60.     mov    al,VALID_OUT [bx - 1]    ; Load the valid output to AL
  61. CLEAN_END:
  62.     pop    cx            ; Restore CX
  63.     pop    di            ; Restore DI
  64.     stosb                ; Store modified AL back to PSP
  65. loop    CLEAN_PARMS            ; Loop until CX is zero
  66. ;
  67.     mov    cx,dx            ; Restore number of bytes in PSP to CX
  68.     mov    dx,2            ; Set DX to look for up to 2 parameters
  69.     mov    bx,offset SOURCE_FILE    ; Set BX to address of 1st parameter
  70.     mov    al,' '                  ; Set up to scan for first non-blank
  71.     mov    di,81h            ; Set DI to PC-DOS parameter pointer
  72. FIND_PARMS:    ; Start looking for parameters, load to program storage
  73. repe    scasb                ; Scan while blanks
  74.     mov    si,di            ; Set SI to second non-blank byte
  75.     dec    si            ; Adjust it to first non-blank byte
  76.     inc    cx            ; Adjust CX to compensate
  77.     jcxz    PARMS_LOADED        ; If CX is zero, no parameters left
  78.     mov    di,bx            ; Set DI to parameter hold area
  79.     mov    ax,cx            ; Store CX to first byte of hold area
  80.     stosb                ; DI is adjusted to second byte here
  81. STORE:    lodsb                ; Load each byte to AL
  82.     cmp    al,' '                  ; Is it a blank?
  83.     jz    END_STORE        ; Yes, end of this parameter
  84.     stosb                ; No, store the byte to hold area
  85. END_STORE:
  86.     loopnz    STORE            ; Keep looking
  87.     sub    [bx],cx         ; Store number of bytes in each
  88.     jcxz    PARMS_LOADED        ; If CX is zero, no more parameters
  89.     dec    byte ptr [bx]        ; parameter to first byte of hold area
  90.     mov    di,si            ; Set up to scan for next non-blank
  91.     dec    di            ; Adjust DI to point to the blank
  92.     inc    cx            ; Adjust CX to compensate
  93.     dec    dx            ; Decrement DX counter
  94.     cmp    dx,0            ; Is DX zero?
  95.     jz    PARMS_LOADED        ; Yes, all expected parameters loaded
  96.     add    bx,PATH_FILE_LEN    ; No, point to next part of hold area
  97.     jmp    FIND_PARMS        ; Go back and look for more
  98. PARMS_LOADED:                ; All parameters are loaded
  99.     cmp    SOURCE_FILE[0],0    ; If there are no bytes in the
  100.     ja    FIX_UP            ; SOURCE_FILE, no parameters present
  101. NO_PARMS_PASSED:            ; Exit with an error if there
  102.     mov    dx,offset NO_PARMS    ; are no parameters passed
  103.     jmp    ERROR_EXIT
  104. FIX_UP:                 ; Fix SOURCE_FILE and TARGET_PATH
  105.     mov    si,offset SOURCE_FILE    ; For Search calls
  106.     lodsb                ; Get Number of bytes
  107.     xor    ah,ah            ; Zero high byte of AX
  108.     mov    di,si            ; Move SI to DI for scan
  109.     add    di,ax            ; Start scan at end of parameter
  110.     dec    di            ; Adjust DI
  111.     mov    cx,ax            ; Set CX to number of bytes
  112.     mov    al,'\'                  ; Scan for the last '\'
  113.     std                ; Set direction flag to reverse
  114. repnz    scasb                ; Scan while not '\'
  115.     jnz    NO_SOURCE_DIR        ; If Zero Flag not set, '\' not found
  116.     add    di,2            ; Add 2 to DI to point to file name
  117.     jmp    SOURCE_FIXED        ; position
  118. NO_SOURCE_DIR:                ; No source directory was specified
  119.     add    di,1            ; Adjust DI
  120.     cmp    SOURCE_FILE[2],':'      ; Check for specified disk drive
  121.     jne    SOURCE_FIXED        ; None present, we're done
  122.     mov    di,offset SOURCE_FILE[3]; Yes, set DI to point to first byte
  123. SOURCE_FIXED:                ; after ':'
  124.     mov    SOURCE_END,di        ; Move DI to SOURCE_END pointer
  125. ;
  126.     cld                ; Set direction flag to forward
  127.     mov    si,offset TARGET_PATH    ; Set up to look for '\' present
  128.     lodsb                ; Get number of bytes
  129.     cmp    al,0            ; If it's zero, no target specified
  130.     je    NO_TARGET
  131.     xor    ah,ah            ; Zero high byte of AX
  132.     add    si,ax            ; Add it to SI to point to end
  133.     dec    si            ; Decrement SI to adjust
  134.     lodsb                ; Look at last byte
  135.     mov    di,si            ; Copy SI to DI
  136.     cmp    al,'\'                  ; Is last byte a '\'?
  137.     je    TARGET_FIXED        ; Yes, everything's fine
  138.     cmp    TARGET_PATH[0],2    ; If TARGET_PATH is 2 bytes long and
  139.     jne    STORE_SLASH        ; is a disk drive specification,
  140.     cmp    TARGET_PATH[2],':'      ; let it default to the current
  141.     je    TARGET_FIXED        ; directory.
  142. STORE_SLASH:                ; Place a '\' at the end of
  143.     mov    al,'\'                  ; TARGET_PATH if user did
  144.     stosb                ; not
  145. TARGET_FIXED:
  146.     mov    TARGET_END,di        ; Move DI to TARGET_END pointer
  147.     jmp    BUFFER_SIZE
  148. NO_TARGET:                ; Set up to allow target path default
  149.     mov    TARGET_END,offset TARGET_PATH + 1      ; to current path
  150. BUFFER_SIZE:                ; Compute size of file buffer
  151.     mov    ax,0fdffh        ; Leave plenty of room in segment
  152.     mov    dx,offset FILE_BUFFER    ; for stack & set DX to end of code
  153.     sub    ax,dx            ; Subtract
  154.     mov    BLKSIZE,ax        ; Save result in BLKSIZE
  155. FIND_FILE:                ; Find first source file
  156.     xor    ax,ax            ; Request to use SOURCE_DTA
  157.     mov    ah,1ah            ; to house FCB for SOURCE_FILE
  158.     mov    dx,offset SOURCE_DTA
  159.     int    21h            ; Call PC-DOS
  160.     mov    dx,offset SOURCE_FILE + 1    ; DX points to SOURCE_FILE
  161.     mov    ah,4eh            ; Request function 4EH (find 1st file)
  162.     mov    cx,0            ; Set CX to zero for normal files only
  163.     int    21h            ; Call PC-DOS
  164.     jnc    FOUND_FILE        ; If no error, first file found
  165.     mov    dx,offset FILE_NOT_FOUND; If no files found, exit
  166.     jmp    ERROR_EXIT        ; program with error message
  167. FOUND_FILE:
  168.     mov    LAST_BLOCK,0        ; Initalize last block read flag
  169.     mov    si,offset SOURCE_DTA+30 ; SI points to source file name in DTA
  170.     mov    di,SOURCE_END        ; DI points to end of source path
  171.     push    si            ; Save pointer to source file name
  172.     mov    cx,13            ; DTA will have 13 bytes
  173. rep    movsb                ; Move name bytes to SOURCE_FILE
  174.     mov    di,TARGET_END        ; DI points to end of target path
  175.     pop    si            ; Recover pointer to source file name
  176.     mov    cx,13            ; DTA will have 13 bytes
  177. rep    movsb                ; Move file name bytes to TARGET_PATH
  178. FIND_TARGET:                ; Find matching target file
  179.     mov    ah,1ah            ; Request to use TARGET_DTA
  180.     xor    al,al            ; to house FCB for TARGET_PATH
  181.     mov    dx,offset TARGET_DTA
  182.     int    21h            ; Call PC-DOS
  183.     mov    ah,4eh            ; Request find 1st file for target
  184.     mov    dx,offset TARGET_PATH+1
  185.     mov    cx,0            ; Set CX to zero for normal files only
  186.     int    21h            ; Call PC-DOS
  187.     jc    OPEN_SOURCE        ; If not found, bypass date & time check
  188. CHECK_TIME_DATE:            ; Check time & date stamps in DTAs
  189.     mov    si,offset SOURCE_DTA+24 ; Load source file date stamp to AX
  190.     lodsw
  191.     mov    dx,ax            ; Save in DX
  192.     mov    si,offset TARGET_DTA+24 ; Load target file date stamp to AX
  193.     lodsw
  194.     cmp    dx,ax            ; If Source file newer, jump
  195.     ja    OPEN_SOURCE        ; to OPEN_SOURCE
  196.     jne    DONT_COPY        ; If Source file older, don't copy it
  197.     mov    si,offset SOURCE_DTA+22 ; Otherwise,
  198.     lodsw                ; load source time stamp to AX
  199.     mov    dx,ax            ; Save in DX
  200.     mov    si,offset TARGET_DTA+22 ; Load target time stamp to AX
  201.     lodsw
  202.     cmp    dx,ax            ; If Source file newer, jump
  203.     ja    OPEN_SOURCE        ; to OPEN_SOURCE
  204.     jmp    DONT_COPY
  205. DONT_COPY:                ; Otherwise,
  206.     call    CLOSE_ALL        ; Close all files
  207.     jmp    NEXT_FILE        ; Check for next file
  208. OPEN_SOURCE:
  209.     mov    ah,3dh            ; Request Open Source File
  210.     mov    dx,offset SOURCE_FILE+1 ; DX points to source file path name
  211.     mov    al,0            ; with read permission only
  212.     int    21h            ; Call PC-DOS
  213.     mov    SOURCE_HANDLE,ax    ; Save handle in memory
  214.     jnc    CREATE_TARGET        ; If no carry, open was good
  215.     mov    dx,offset SOURCE_ERROR    ; Otherwise, exit with error
  216.     mov    SOURCE_HANDLE,0     ; Make sure CLOSE_ALL ignores handle
  217.     jmp    ERROR_EXIT
  218. CREATE_TARGET:
  219.     xor    ax,ax
  220.     mov    ah,3ch            ; Request create & open a file
  221.     mov    dx,offset TARGET_PATH+1 ; named the target file
  222.     xor    cx,cx            ; with normal attribute
  223.     int    21h            ; Call PC-DOS
  224.     mov    TARGET_HANDLE,ax    ; Save target handle
  225.     jnc    PROCEED_TO_COPY     ; If no carry, create / open is ok
  226.     mov    dx,offset CREATE_ERROR    ; Otherwise, exit with an error
  227.     mov    TARGET_HANDLE,0     ; Make sure CLOSE_ALL ignores target
  228.     jmp    ERROR_EXIT
  229. PROCEED_TO_COPY:            ; The heart of the matter
  230.     mov    si,offset SOURCE_FILE+1 ; Point to source file
  231. START1: lodsb                ; Load each byte to AL
  232.     cmp    al,0            ; If ASCII 0, end of field
  233.     je    DOTS
  234.     mov    dl,al            ; Copy byte to DL for funciton 2H
  235.     mov    ah,2h            ; Request function 2H
  236.     int    21h            ; Call PC-DOS
  237.     jmp    START1            ; Get next character
  238. DOTS:    mov    ah,9h            ; Confirm start of task
  239.     mov    dx,offset CONFIRM_MSG_1
  240.     int    21h
  241. KEEP_COPYING:
  242.     mov    ah,3fh            ; Request read block of data
  243.     mov    cx,BLKSIZE        ; BLKSIZE bytes long
  244.     mov    bx,SOURCE_HANDLE    ; from source file
  245.     mov    dx,offset FILE_BUFFER    ; into buffer
  246.     int    21h            ; Call PC-DOS
  247.     cmp    ax,0            ; If AX is 0, no bytes were
  248.     je    FINISH            ; read, and we're done
  249.     mov    cx,ax            ; Move AX to CX for write call (below)
  250.     cmp    cx,BLKSIZE        ; Check number of bytes read against
  251.     je    MORE_TO_COME        ; request.  If equal, we got them all,
  252.     mov    LAST_BLOCK,1        ; otherwise, it's the last block of file
  253. MORE_TO_COME:                ;
  254.     push    cx            ; Save requested write count on stack
  255.     mov    ah,40h            ; Request write block of data
  256.     mov    bx,TARGET_HANDLE    ; to target file
  257.     mov    dx,offset FILE_BUFFER    ; from file buffer
  258.     int    21h            ; Call PC-DOS
  259.     pop    cx            ; Recover requested write count
  260.     cmp    ax,cx            ; If CX equals AX,
  261.     je    WRITE_OK        ; write was successful,
  262. DISK_FULL:
  263.     call    CLOSE_ALL        ; Otherwise disk is full -- close files
  264.     mov    ah,41h            ; Request erase file
  265.     mov    dx,offset TARGET_PATH+1 ; for incomplete target.
  266.     int    21h            ; Call PC-DOS
  267.     mov    dx,offset TARGET_FULL
  268.     mov    ah,9h
  269.     int    21h
  270. READ_KEYBOARD:                ; Prompt requested [Enter] key
  271.     mov    ah,8h            ; Make sure [Ctrl]-[Break] is detected
  272.     int    21h            ; Call PC-DOS for key
  273.     cmp    al,13            ; Check for [Enter]
  274.     jne    READ_KEYBOARD        ; (no extended codes are 13)
  275.     mov    cx,2
  276. END_FULL:
  277.     mov    dx,offset END_LINE    ; Send a new line to screen
  278.     mov    ah,9h
  279.     int    21h
  280.     loop    END_FULL
  281.     jmp    FOUND_FILE        ; Re-start from FOUND_FILE:
  282. WRITE_OK:
  283.     cmp    LAST_BLOCK,1        ; If this is the last block,
  284.     je    FINISH            ; we're done
  285.     jmp    KEEP_COPYING        ; Otherwise, keep going.
  286. FINISH:                 ; Force target time & date stamps
  287.     mov    ah,57h            ; to equal source, close files
  288.     mov    al,0            ; Request get time and date stamos
  289.     mov    bx,SOURCE_HANDLE    ; for source file
  290.     int    21h            ; DX & CX contain data
  291.     mov    ah,57h            ; Request set date and time
  292.     mov    al,1            ; to force target file to
  293.     mov    bx,TARGET_HANDLE    ; source stamp
  294.     int    21h            ; Call PC-DOS
  295.     call    CLOSE_ALL        ; Go close all files
  296.     mov    dx,offset CONFIRM_MSG_2 ; Confirm completion of task
  297.     mov    ah,9h            ; Request function 9H
  298.     int    21h            ; Call PC-DOS
  299.     mov    si,offset TARGET_PATH+1 ; Point to source file
  300. START2: lodsb                ; Load each byte to AL
  301.     cmp    al,0            ; If ASCII 0, end of field
  302.     je    CR_LF
  303.     mov    dl,al            ; Copy byte to DL for funciton 2H
  304.     mov    ah,2h            ; Request function 2H
  305.     int    21h            ; Call PC-DOS
  306.     jmp    START2            ; Get next character
  307. CR_LF:    mov    dx,offset END_LINE    ; Terminate display line
  308.     mov    ah,9h            ; Request function 9H
  309.     int    21h
  310.     mov    EVENT_FLAG,1        ; Set flag to indicate file was copied
  311. NEXT_FILE:                ; Go Look for next file
  312.     xor    ax,ax
  313.     mov    ah,1ah            ; Request to use SOURCE_DTA
  314.     mov    dx,offset SOURCE_DTA    ; to house FCB for SOURCE_FILE
  315.     int    21h            ; Call PC-DOS
  316.     mov    ah,4fh            ; Request find next source file
  317.     mov    cx,0            ; Normal files only
  318.     int    21h            ; Call PC-DOS
  319.     jnc    FOUND_ANOTHER        ; No error, another file was found
  320.     jmp    END_OK            ; Error, we're done finding files
  321. FOUND_ANOTHER:
  322.     jmp    FOUND_FILE        ; Go process next file
  323. END_OK: cmp    EVENT_FLAG,1        ; Did anything happen?
  324.     je    EXIT            ; Yes, just exit
  325.     mov    dx,offset NOTHING_TO_DO ; No, tell user that nothing happened
  326.     mov    ah,9h
  327.     int    21h
  328. EXIT:    int    20h            ; Exit to PC-DOS
  329. ERROR_EXIT:                ; Print Error Message and Exit
  330.     push    dx            ; Save error message pointer on stack
  331.     mov    ah,9            ; Display error header
  332.     mov    dx,offset ERR_HEAD
  333.     int    21h
  334.     mov    ah,9            ; Display error message
  335.     pop    dx
  336.     int    21h
  337.     mov    ah,9            ; Display error tail
  338.     mov    dx,offset ERR_TAIL
  339.     call    CLOSE_ALL
  340.     int    21h
  341.     int    20h            ; Exit to PC-DOS
  342.  
  343.  
  344. CLOSE_ALL    proc
  345.     cmp    SOURCE_HANDLE,0     ; Check for valid SOURCE_HANDLE
  346.     je    CLOSE_TARGET        ; None, then go close target
  347.     mov    ah,3eh            ; Request close file
  348.     mov    bx,SOURCE_HANDLE    ; for source handle
  349.     int    21h            ; Call PC-DOS
  350.     mov    SOURCE_HANDLE,0     ; Refresh handle
  351. CLOSE_TARGET:
  352.     cmp    TARGET_HANDLE,0     ; Check for valid TARGET_HANDLE
  353.     je    CLOSE_RETURN        ; None, then return
  354.     mov    bx,TARGET_HANDLE    ; Request close file
  355.     mov    ah,3eh            ; for target handle
  356.     int    21h            ; Call PC-DOS
  357.     mov    TARGET_HANDLE,0     ; Refresh handle
  358. CLOSE_RETURN:
  359.     ret
  360. CLOSE_ALL    endp
  361. FILE_BUFFER    label    word
  362. BAC    ends
  363.     end    BEGIN
  364.